import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import seaborn as sns; sns.set(style="ticks", color_codes=True)
import matplotlib.pyplot as plt
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import seaborn as sns
import plotly.express as px
%matplotlib inline
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected = False)
C:\Users\Usuario\anaconda3\lib\site-packages\pandas\core\arrays\masked.py:60: UserWarning: Pandas requires version '1.3.6' or newer of 'bottleneck' (version '1.3.5' currently installed). from pandas.core import (
Exploración Inicial de Datos:
Carga del Dataset:
Cargar el conjunto de datos en el entorno de trabajo.
Asegurarse de que los datos se hayan cargado correctamente y se encuentren en el formato adecuado.
Revisión General:
Realizar una revisión general del conjunto de datos para obtener una visión inicial de su estructura. Incluyan el número de filas y columnas, nombres de columnas, y tipos de datos de cada columna.
Cargar el conjunto de datos en el entorno de trabajo
Realizar una revisión general
# dataset original
df_1=pd.read_csv('C:\\Users\\Usuario\\Desktop\\2024\\materias\\CDIA\\2semestre\\pp1-cdia23\\ejemplo suply chain\\DataCoSupplyChainDataset.csv\\para jupyter\\SinAcento.csv', encoding='latin1', sep=';', low_memory=False)
pd.set_option('display.max_rows', 60) #muestra 60 columnas
pd.set_option('display.max_columns', 100) # 100 filas
pd.set_option('display.width', 1000)
# detalle
df_1.head()
| Type | Days for shipping (real) | Days for shipment (scheduled) | Benefit per order | Sales per customer | Delivery Status | Late_delivery_risk | Category Id | Category Name | Customer City | Customer Country | Customer Email | Customer Fname | Customer Id | Customer Lname | Customer Password | Customer Segment | Customer State | Customer Street | Customer Zipcode | Department Id | Department Name | Latitude | Longitude | Market | Order City | Order Country | Order Customer Id | order date (DateOrders) | Order Id | Order Item Cardprod Id | Order Item Discount | Order Item Discount Rate | Order Item Id | Order Item Product Price | Order Item Profit Ratio | Order Item Quantity | Sales | Order Item Total | Order Profit Per Order | Order Region | Order State | Order Status | Order Zipcode | Product Card Id | Product Category Id | Product Description | Product Image | Product Name | Product Price | Product Status | shipping date (DateOrders) | Shipping Mode | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | DEBIT | 3 | 4 | 9.125000e+01 | 3.146400e+09 | Advance shipping | 0 | 73 | Sporting Goods | Caguas | Puerto Rico | XXXXXXXXX | Cally | 20755 | Holloway | XXXXXXXXX | Consumer | PR | 5365 Noble Nectar Island | 725.0 | 2 | Fitness | 182.514.534 | -6.603.705.597 | Pacific Asia | Bekasi | Indonesia | 20755 | 1/31/2018 22:56 | 77202 | 1360 | 1.310.999.966 | 0.04 | 180517 | 327.75 | 0.289999992 | 1 | 327.75 | 3.146.400.146 | 91.25 | Southeast Asia | Java Occidental | COMPLETE | NaN | 1360 | 73 | NaN | http://images.acmesports.sports/Smart+watch | Smart watch | 327.75 | 0 | 2/3/2018 22:56 | Standard Class |
| 1 | TRANSFER | 5 | 4 | -2.490900e+09 | 3.113600e+09 | Late delivery | 1 | 73 | Sporting Goods | Caguas | Puerto Rico | XXXXXXXXX | Irene | 19492 | Luna | XXXXXXXXX | Consumer | PR | 2679 Rustic Loop | 725.0 | 2 | Fitness | 1.827.945.137 | -660.370.636 | Pacific Asia | Bikaner | India | 19492 | 1/13/2018 12:27 | 75939 | 1360 | 1.638.999.939 | 0.05 | 179254 | 327.75 | -0.800000012 | 1 | 327.75 | 3.113.599.854 | -2.490.899.963 | South Asia | Rajastán | PENDING | NaN | 1360 | 73 | NaN | http://images.acmesports.sports/Smart+watch | Smart watch | 327.75 | 0 | 1/18/2018 12:27 | Standard Class |
| 2 | CASH | 4 | 4 | -2.477800e+09 | 3.097200e+09 | Shipping on time | 0 | 73 | Sporting Goods | San Jose | EE. UU. | XXXXXXXXX | Gillian | 19491 | Maldonado | XXXXXXXXX | Consumer | CA | 8510 Round Bear Gate | 95125.0 | 2 | Fitness | 3.729.223.251 | -121.881.279 | Pacific Asia | Bikaner | India | 19491 | 1/13/2018 12:06 | 75938 | 1360 | 1.803.000.069 | 0.06 | 179253 | 327.75 | -0.800000012 | 1 | 327.75 | 3.097.200.012 | -2.477.799.988 | South Asia | Rajastán | CLOSED | NaN | 1360 | 73 | NaN | http://images.acmesports.sports/Smart+watch | Smart watch | 327.75 | 0 | 1/17/2018 12:06 | Standard Class |
| 3 | DEBIT | 3 | 4 | 2.286000e+09 | 3.048100e+09 | Advance shipping | 0 | 73 | Sporting Goods | Los Angeles | EE. UU. | XXXXXXXXX | Tana | 19490 | Tate | XXXXXXXXX | Home Office | CA | 3200 Amber Bend | 90027.0 | 2 | Fitness | 3.412.594.605 | -1.182.910.156 | Pacific Asia | Townsville | Australia | 19490 | 1/13/2018 11:45 | 75937 | 1360 | 2.294.000.053 | 0.07 | 179252 | 327.75 | 0.079999998 | 1 | 327.75 | 3.048.099.976 | 2.286.000.061 | Oceania | Queensland | COMPLETE | NaN | 1360 | 73 | NaN | http://images.acmesports.sports/Smart+watch | Smart watch | 327.75 | 0 | 1/16/2018 11:45 | Standard Class |
| 4 | PAYMENT | 2 | 4 | 1.342100e+09 | 2.982500e+02 | Advance shipping | 0 | 73 | Sporting Goods | Caguas | Puerto Rico | XXXXXXXXX | Orli | 19489 | Hendricks | XXXXXXXXX | Corporate | PR | 8671 Iron Anchor Corners | 725.0 | 2 | Fitness | 1.825.376.892 | -6.603.704.834 | Pacific Asia | Townsville | Australia | 19489 | 1/13/2018 11:24 | 75936 | 1360 | 29.5 | 0.09 | 179251 | 327.75 | 0.449999988 | 1 | 327.75 | 298.25 | 1.342.100.067 | Oceania | Queensland | PENDING_PAYMENT | NaN | 1360 | 73 | NaN | http://images.acmesports.sports/Smart+watch | Smart watch | 327.75 | 0 | 1/15/2018 11:24 | Standard Class |
df_1.shape
(180519, 53)
Operaciones sobr el conjunto de datos
# filtrar filas
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
#df_1 = df[df['Order Country'] == 'Argentina','Brasil','Mexico']
df = df_1[df_1['Order Country'].isin(['Argentina', 'Brasil', 'Mexico'])]
#df= df_1[(df['Order Country'] == 'Argentina') | (df_1['Order Country'] == 'Brasil') | (df_1['Order Country'] == 'Mexico')]
df.head()
| Type | Days for shipping (real) | Days for shipment (scheduled) | Benefit per order | Sales per customer | Delivery Status | Late_delivery_risk | Category Id | Category Name | Customer City | Customer Country | Customer Email | Customer Fname | Customer Id | Customer Lname | Customer Password | Customer Segment | Customer State | Customer Street | Customer Zipcode | Department Id | Department Name | Latitude | Longitude | Market | Order City | Order Country | Order Customer Id | order date (DateOrders) | Order Id | Order Item Cardprod Id | Order Item Discount | Order Item Discount Rate | Order Item Id | Order Item Product Price | Order Item Profit Ratio | Order Item Quantity | Sales | Order Item Total | Order Profit Per Order | Order Region | Order State | Order Status | Order Zipcode | Product Card Id | Product Category Id | Product Description | Product Image | Product Name | Product Price | Product Status | shipping date (DateOrders) | Shipping Mode | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 84 | PAYMENT | 4 | 2 | 2.347000e+09 | 144.0 | Late delivery | 1 | 24 | Women's Apparel | Caguas | Puerto Rico | XXXXXXXXX | Mary | 8541 | Smith | XXXXXXXXX | Home Office | PR | 5700 Little Circle | 725.0 | 5 | Golf | 1.829.609.299 | -6.637.050.629 | LATAM | Juazeiro | Brasil | 8541 | 4/11/2017 15:49 | 56973 | 502 | 6 | 0.04 | 142502 | 50 | 0.159999996 | 3 | 150 | 144 | 2.346.999.931 | South America | Bahía | PENDING_PAYMENT | NaN | 502 | 24 | NaN | http://images.acmesports.sports/Nike+Men%27s+D... | Nike Men's Dri-FIT Victory Golf Polo | 50 | 0 | 4/15/2017 15:49 | Second Class |
| 86 | PAYMENT | 6 | 2 | 4.366000e+09 | 139.5 | Late delivery | 1 | 24 | Women's Apparel | Caguas | Puerto Rico | XXXXXXXXX | Mary | 3752 | Vega | XXXXXXXXX | Home Office | PR | 7840 Umber Sky Villas | 725.0 | 5 | Golf | 182.105.732 | -6.637.058.258 | LATAM | Mexico City | Mexico | 3752 | 3/16/2017 2:54 | 55155 | 502 | 10.5 | 0.07 | 137932 | 50 | 0.310000002 | 3 | 150 | 139.5 | 4.365.999.985 | Central America | Distrito Federal | PENDING_PAYMENT | NaN | 502 | 24 | NaN | http://images.acmesports.sports/Nike+Men%27s+D... | Nike Men's Dri-FIT Victory Golf Polo | 50 | 0 | 3/22/2017 2:54 | Second Class |
| 87 | PAYMENT | 2 | 2 | 1.320000e+09 | 132.0 | Shipping on time | 0 | 24 | Women's Apparel | Caguas | Puerto Rico | XXXXXXXXX | Wayne | 4673 | Hodges | XXXXXXXXX | Home Office | PR | 7509 Iron Concession | 725.0 | 5 | Golf | 1.820.111.656 | -6.637.059.021 | LATAM | Tlaquepaque | Mexico | 4673 | 3/29/2015 10:33 | 5991 | 502 | 18 | 0.12 | 14921 | 50 | 0.100000001 | 3 | 150 | 132 | 1.319.999.981 | Central America | Jalisco | PENDING_PAYMENT | NaN | 502 | 24 | NaN | http://images.acmesports.sports/Nike+Men%27s+D... | Nike Men's Dri-FIT Victory Golf Polo | 50 | 0 | 3/31/2015 10:33 | Second Class |
| 88 | PAYMENT | 4 | 2 | 4.620000e+09 | 132.0 | Late delivery | 1 | 24 | Women's Apparel | Caguas | Puerto Rico | XXXXXXXXX | Mary | 5367 | Mccormick | XXXXXXXXX | Home Office | PR | 2199 Silver Autumn Key | 725.0 | 5 | Golf | 1.821.469.116 | -6.637.051.392 | LATAM | Puebla | Mexico | 5367 | 2/3/2015 00:28 | 2263 | 502 | 18 | 0.12 | 5671 | 50 | 0.349999994 | 3 | 150 | 132 | 4.620.000.076 | Central America | Puebla | PENDING_PAYMENT | NaN | 502 | 24 | NaN | http://images.acmesports.sports/Nike+Men%27s+D... | Nike Men's Dri-FIT Victory Golf Polo | 50 | 0 | 2/7/2015 00:28 | Second Class |
| 89 | PAYMENT | 4 | 2 | 1.044000e+09 | 130.5 | Late delivery | 1 | 24 | Women's Apparel | Caguas | Puerto Rico | XXXXXXXXX | Mary | 5367 | Mccormick | XXXXXXXXX | Home Office | PR | 2199 Silver Autumn Key | 725.0 | 5 | Golf | 1.821.469.116 | -6.637.051.392 | LATAM | Puebla | Mexico | 5367 | 2/3/2015 00:28 | 2263 | 502 | 19.5 | 0.13 | 5669 | 50 | 0.079999998 | 3 | 150 | 130.5 | 1.043.999.958 | Central America | Puebla | PENDING_PAYMENT | NaN | 502 | 24 | NaN | http://images.acmesports.sports/Nike+Men%27s+D... | Nike Men's Dri-FIT Victory Golf Polo | 50 | 0 | 2/7/2015 00:28 | Second Class |
df.tail()
| Type | Days for shipping (real) | Days for shipment (scheduled) | Benefit per order | Sales per customer | Delivery Status | Late_delivery_risk | Category Id | Category Name | Customer City | Customer Country | Customer Email | Customer Fname | Customer Id | Customer Lname | Customer Password | Customer Segment | Customer State | Customer Street | Customer Zipcode | Department Id | Department Name | Latitude | Longitude | Market | Order City | Order Country | Order Customer Id | order date (DateOrders) | Order Id | Order Item Cardprod Id | Order Item Discount | Order Item Discount Rate | Order Item Id | Order Item Product Price | Order Item Profit Ratio | Order Item Quantity | Sales | Order Item Total | Order Profit Per Order | Order Region | Order State | Order Status | Order Zipcode | Product Card Id | Product Category Id | Product Description | Product Image | Product Name | Product Price | Product Status | shipping date (DateOrders) | Shipping Mode | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 179618 | TRANSFER | 6 | 4 | 1.337500e+02 | 2.729500e+09 | Late delivery | 1 | 17 | Cleats | Caguas | Puerto Rico | XXXXXXXXX | Brenda | 12354 | Wells | XXXXXXXXX | Consumer | PR | 3762 Amber Estates | 725.0 | 4 | Apparel | 1.823.072.052 | -6.637.063.599 | LATAM | Goiânia | Brasil | 12354 | 4/18/2015 13:41 | 7370 | 365 | 27 | 0.09 | 18457 | 5.999.000.168 | 0.49000001 | 5 | 2.999.500.122 | 2.729.500.122 | 133.75 | South America | Goiás | PENDING | NaN | 365 | 17 | NaN | http://images.acmesports.sports/Perfect+Fitnes... | Perfect Fitness Perfect Rip Deck | 5.999.000.168 | 0 | 4/24/2015 13:41 | Standard Class |
| 179621 | TRANSFER | 3 | 4 | -2.610000e+09 | 2.609600e+09 | Advance shipping | 0 | 17 | Cleats | Juana Diaz | Puerto Rico | XXXXXXXXX | Mary | 10344 | Smith | XXXXXXXXX | Consumer | PR | 2839 Grand Timber Canyon | 795.0 | 4 | Apparel | 1.805.199.051 | -6.650.184.631 | LATAM | Villahermosa | Mexico | 10344 | 5/16/2017 21:33 | 59387 | 365 | 3.899.000.168 | 0.13 | 148676 | 5.999.000.168 | -0.100000001 | 5 | 2.999.500.122 | 2.609.599.915 | -2.610.000.038 | Central America | Tabasco | PENDING | NaN | 365 | 17 | NaN | http://images.acmesports.sports/Perfect+Fitnes... | Perfect Fitness Perfect Rip Deck | 5.999.000.168 | 0 | 5/19/2017 21:33 | Standard Class |
| 179623 | TRANSFER | 2 | 4 | 1.174300e+09 | 2.609600e+09 | Advance shipping | 0 | 17 | Cleats | Caguas | Puerto Rico | XXXXXXXXX | Mary | 8917 | Smith | XXXXXXXXX | Consumer | PR | 4992 Jagged Forest Subdivision | 725.0 | 4 | Apparel | 1.822.487.068 | -6.637.052.155 | LATAM | Barueri | Brasil | 8917 | 4/13/2017 14:25 | 57106 | 365 | 3.899.000.168 | 0.13 | 142839 | 5.999.000.168 | 0.449999988 | 5 | 2.999.500.122 | 2.609.599.915 | 1.174.300.003 | South America | São Paulo | PENDING | NaN | 365 | 17 | NaN | http://images.acmesports.sports/Perfect+Fitnes... | Perfect Fitness Perfect Rip Deck | 5.999.000.168 | 0 | 4/15/2017 14:25 | Standard Class |
| 179624 | TRANSFER | 3 | 4 | 4.844000e+09 | 2.549600e+09 | Advance shipping | 0 | 17 | Cleats | Caguas | Puerto Rico | XXXXXXXXX | Mary | 9204 | Harris | XXXXXXXXX | Consumer | PR | 8713 Quaking Abbey | 725.0 | 4 | Apparel | 1.828.453.636 | -6.637.060.547 | LATAM | Maceió | Brasil | 9204 | 5/27/2017 16:48 | 60127 | 365 | 4.499.000.168 | 0.15 | 150462 | 5.999.000.168 | 0.189999998 | 5 | 2.999.500.122 | 2.549.600.067 | 4.843.999.863 | South America | Alagoas | PENDING | NaN | 365 | 17 | NaN | http://images.acmesports.sports/Perfect+Fitnes... | Perfect Fitness Perfect Rip Deck | 5.999.000.168 | 0 | 5/30/2017 16:48 | Standard Class |
| 179628 | TRANSFER | 3 | 4 | 6.749000e+09 | 2.249600e+09 | Advance shipping | 0 | 17 | Cleats | Caguas | Puerto Rico | XXXXXXXXX | Jerry | 7024 | Smith | XXXXXXXXX | Consumer | PR | 5149 Rocky Pine Moor | 725.0 | 4 | Apparel | 1.822.907.066 | -6.637.058.258 | LATAM | Mexico City | Mexico | 7024 | 5/19/2017 3:51 | 59542 | 365 | 7.498.999.786 | 0.25 | 149029 | 5.999.000.168 | 0.300000012 | 5 | 2.999.500.122 | 2.249.600.067 | 6.748.999.786 | Central America | Distrito Federal | PENDING | NaN | 365 | 17 | NaN | http://images.acmesports.sports/Perfect+Fitnes... | Perfect Fitness Perfect Rip Deck | 5.999.000.168 | 0 | 5/22/2017 3:51 | Standard Class |
df.shape
(23090, 53)
Información general del DataFrame ---tipo de datos---
df.info()
<class 'pandas.core.frame.DataFrame'> Index: 23090 entries, 84 to 179628 Data columns (total 53 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Type 23090 non-null object 1 Days for shipping (real) 23090 non-null int64 2 Days for shipment (scheduled) 23090 non-null int64 3 Benefit per order 23090 non-null float64 4 Sales per customer 23090 non-null float64 5 Delivery Status 23090 non-null object 6 Late_delivery_risk 23090 non-null int64 7 Category Id 23090 non-null int64 8 Category Name 23090 non-null object 9 Customer City 23090 non-null object 10 Customer Country 23090 non-null object 11 Customer Email 23090 non-null object 12 Customer Fname 23090 non-null object 13 Customer Id 23090 non-null int64 14 Customer Lname 23090 non-null object 15 Customer Password 23090 non-null object 16 Customer Segment 23090 non-null object 17 Customer State 23090 non-null object 18 Customer Street 23090 non-null object 19 Customer Zipcode 23090 non-null float64 20 Department Id 23090 non-null int64 21 Department Name 23090 non-null object 22 Latitude 23090 non-null object 23 Longitude 23090 non-null object 24 Market 23090 non-null object 25 Order City 23090 non-null object 26 Order Country 23090 non-null object 27 Order Customer Id 23090 non-null int64 28 order date (DateOrders) 23090 non-null object 29 Order Id 23090 non-null int64 30 Order Item Cardprod Id 23090 non-null int64 31 Order Item Discount 23090 non-null object 32 Order Item Discount Rate 23090 non-null float64 33 Order Item Id 23090 non-null int64 34 Order Item Product Price 23090 non-null object 35 Order Item Profit Ratio 23090 non-null object 36 Order Item Quantity 23090 non-null int64 37 Sales 23090 non-null object 38 Order Item Total 23090 non-null object 39 Order Profit Per Order 23090 non-null object 40 Order Region 23090 non-null object 41 Order State 23090 non-null object 42 Order Status 23090 non-null object 43 Order Zipcode 0 non-null float64 44 Product Card Id 23090 non-null int64 45 Product Category Id 23090 non-null int64 46 Product Description 0 non-null float64 47 Product Image 23090 non-null object 48 Product Name 23090 non-null object 49 Product Price 23090 non-null object 50 Product Status 23090 non-null int64 51 shipping date (DateOrders) 23090 non-null object 52 Shipping Mode 23090 non-null object dtypes: float64(6), int64(14), object(33) memory usage: 9.5+ MB
La informacion general indica que los datos en las columnas del tipo "object", significa que son un cadena de texto u otro tipo no numerico
#product description y Order Zipcode esta en blanco toda la columna
# Product state es "0" para toda la columna
Verificar si existen filas duplicadas o espacios vacios.
# verificar filas duplicadas
duplicados=df[df.duplicated()]
if duplicados.empty:
print("No hay filas duplicadas en el DataFrame.")
else:
print("Las siguientes filas están duplicadas:")
print(duplicados)
No hay filas duplicadas en el DataFrame.
# verificar espacios vacios
hay_vacios = df.isna().any().any()
if hay_vacios:
print("El DataFrame contiene valores vacíos.")
else:
print("El DataFrame no contiene valores vacíos.")
El DataFrame contiene valores vacíos.
# quitar columnas vacias
df = df.drop(['Product Description', 'Order Zipcode', 'Product Status'], axis=1)
# quitar columnas vacias
#ELIMINAMOS FILAS DEL DATAFRAME QUE NO USAMOS.
columnas_a_eliminar = ['Sales per customer','Category Id','Customer City','Customer Email','Customer Fname','Customer Lname',
'Customer Password','Customer State','Customer Street','Customer Zipcode','Department Id','Department Name','Latitude',
'Longitude','Market','Order City','Order Customer Id','Order Item Cardprod Id','Order Item Discount', 'Order Item Discount Rate',
'Order Item Profit Ratio','Product Image']
df = df.drop(columns=columnas_a_eliminar)
cinco ultimas filas
número de filas y columnas
df.shape
(23090, 28)
nombres de columnas
df.columns
Index(['Type', 'Days for shipping (real)', 'Days for shipment (scheduled)', 'Benefit per order', 'Delivery Status', 'Late_delivery_risk', 'Category Name', 'Customer Country', 'Customer Id', 'Customer Segment', 'Order Country', 'order date (DateOrders)', 'Order Id', 'Order Item Id', 'Order Item Product Price', 'Order Item Quantity', 'Sales', 'Order Item Total', 'Order Profit Per Order', 'Order Region', 'Order State', 'Order Status', 'Product Card Id', 'Product Category Id', 'Product Name', 'Product Price', 'shipping date (DateOrders)', 'Shipping Mode'], dtype='object')
# trabajo previo
# 1- filtrar el set de datos original por pais para abarcar solo argentina, brasil y mexico
# 2- quitar columnas
#EL DATAFRAME RESULTANTE DE ESTE PROCESO SE EMPLEA PARA TRABAJAR
#CAMBIAR LAS COLUMNAS A ESPAÑOL
#// prueba para cambiar los valores de las columnas a español
df_espanol=df
#renombro la columna porque tiene espacios
df_espanol.rename(columns={'Category Name':'Categoria',
'Type':'Pago'
,'Days for shipping (real)':'DiasEnvio(Real)'
, 'Days for shipment (scheduled)':'DiasEnvio(Programado)'
, 'Benefit per order':'BeneficioPorPedido'
, 'Delivery Status':'EstadoEntrega'
, 'Late_delivery_risk':'RiesgoEntregaTardia'
, 'Category Name':'Categoria'
, 'Customer Country':'PaisCliente'
, 'Customer Id':'IDCliente'
, 'Customer Segment':'SegmentoCliente'
, 'Order Country':'PaisPedido'
, 'order date (DateOrders)':'FechaPedido'
, 'Order Id':'IDPedido'
, 'Order Item Id':'IDArticuloPedido'
, 'Order Item Product Price':'PrecioArticuloPedido'
, 'Order Item Quantity':'CantidadArticulosPedido'
, 'Sales':'Ventas'
, 'Order Item Total':'TotalArticulosPedido'
, 'Order Profit Per Order':'GananciaPorPedido'
, 'Order Region':'RegionPedido'
, 'Order State':'DestinoPedido'
, 'Order Status':'EstadoPedido'
, 'Product Card Id':'IDProducto'
, 'Product Category Id':'CategoriaProducto'
, 'Product Name':'NombreProducto'
, 'Product Price':'PrecioProducto'
, 'shipping date (DateOrders)':'FechaEnvio'
, 'Shipping Mode':'ModoEnvio'
},inplace=True)
df_espanol.info()
<class 'pandas.core.frame.DataFrame'> Index: 23090 entries, 84 to 179628 Data columns (total 28 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Pago 23090 non-null object 1 DiasEnvio(Real) 23090 non-null int64 2 DiasEnvio(Programado) 23090 non-null int64 3 BeneficioPorPedido 23090 non-null float64 4 EstadoEntrega 23090 non-null object 5 RiesgoEntregaTardia 23090 non-null int64 6 Categoria 23090 non-null object 7 PaisCliente 23090 non-null object 8 IDCliente 23090 non-null int64 9 SegmentoCliente 23090 non-null object 10 PaisPedido 23090 non-null object 11 FechaPedido 23090 non-null object 12 IDPedido 23090 non-null int64 13 IDArticuloPedido 23090 non-null int64 14 PrecioArticuloPedido 23090 non-null object 15 CantidadArticulosPedido 23090 non-null int64 16 Ventas 23090 non-null object 17 TotalArticulosPedido 23090 non-null object 18 GananciaPorPedido 23090 non-null object 19 RegionPedido 23090 non-null object 20 DestinoPedido 23090 non-null object 21 EstadoPedido 23090 non-null object 22 IDProducto 23090 non-null int64 23 CategoriaProducto 23090 non-null int64 24 NombreProducto 23090 non-null object 25 PrecioProducto 23090 non-null object 26 FechaEnvio 23090 non-null object 27 ModoEnvio 23090 non-null object dtypes: float64(1), int64(9), object(18) memory usage: 5.1+ MB
Conteo de valores únicos por columna:
df_espanol.nunique()
Pago 4 DiasEnvio(Real) 7 DiasEnvio(Programado) 4 BeneficioPorPedido 8792 EstadoEntrega 4 RiesgoEntregaTardia 2 Categoria 31 PaisCliente 2 IDCliente 5714 SegmentoCliente 3 PaisPedido 3 FechaPedido 7687 IDPedido 7687 IDArticuloPedido 23090 PrecioArticuloPedido 50 CantidadArticulosPedido 5 Ventas 164 TotalArticulosPedido 1575 GananciaPorPedido 8792 RegionPedido 2 DestinoPedido 76 EstadoPedido 9 IDProducto 87 CategoriaProducto 32 NombreProducto 87 PrecioProducto 50 FechaEnvio 7582 ModoEnvio 4 dtype: int64
Verificar si existen filas duplicadas o espacios vacios.
# verificar filas duplicadas
duplicados=df_espanol[df.duplicated()]
if duplicados.empty:
print("No hay filas duplicadas en el DataFrame.")
else:
print("Las siguientes filas están duplicadas:")
print(duplicados)
No hay filas duplicadas en el DataFrame.
# verificar espacios vacios
hay_vacios = df_espanol.isna().any().any()
if hay_vacios:
print("El DataFrame contiene valores vacíos.")
else:
print("El DataFrame no contiene valores vacíos.")
El DataFrame no contiene valores vacíos.
# FIN DE LA PRIMERA PARTE: Exploración Inicial de Datos:
# 2 PARTE: ANALISIS UNIVARIADO
# VER LOS VALORES DE UNA VARIABLE
df_espanol.Categoria.unique()
array(["Women's Apparel", 'Shop By Sport', 'Electronics',
'Baseball & Softball', 'Cardio Equipment', 'Boxing & MMA',
'Cleats', "Girls' Apparel", 'Accessories', 'Golf Balls',
'Trade-In', 'Hockey', 'Camping & Hiking', 'Fishing',
"Men's Footwear", 'Soccer', 'Fitness Accessories',
"Kids' Golf Clubs", 'Tennis & Racquet', 'Lacrosse',
'Hunting & Shooting', 'As Seen on TV!', 'Strength Training',
'Golf Gloves', 'Golf Bags & Carts', 'Golf Shoes', 'Golf Apparel',
"Women's Golf Clubs", "Men's Golf Clubs", 'Water Sports',
'Indoor/Outdoor Games'], dtype=object)
df_espanol.Pago.unique()
array(['PAYMENT', 'TRANSFER', 'DEBIT', 'CASH'], dtype=object)
df_espanol.ModoEnvio.unique()
array(['Second Class', 'Standard Class', 'First Class', 'Same Day'],
dtype=object)
df_espanol.EstadoEntrega.unique()
array(['Late delivery', 'Shipping on time', 'Advance shipping',
'Shipping canceled'], dtype=object)
df_espanol.EstadoEntrega.unique()
array(['Late delivery', 'Shipping on time', 'Advance shipping',
'Shipping canceled'], dtype=object)
#HASTA ACA ESTA TODO BIEN------------
Distribución de Variables: Realizar un análisis de las variables individuales para entender su distribución. Utilizar histogramas, boxplots y estadísticas descriptivas (media, mediana, desviación estándar, etc.) para las variables numéricas. Para las variables categóricas, calcular frecuencias y proporciones.
Identificación de Outliers: Detectar posibles outliers en las variables numéricas utilizando técnicas como el análisis de boxplots o el cálculo del z-score.
#EXPLORAMOS LOS DATOS:
#Obtenemos estadísticas descriptivas sobre las columnas numéricas del conjunto de datos:
df.describe()
| DiasEnvio(Real) | DiasEnvio(Programado) | BeneficioPorPedido | RiesgoEntregaTardia | IDCliente | IDPedido | IDArticuloPedido | CantidadArticulosPedido | IDProducto | CategoriaProducto | |
|---|---|---|---|---|---|---|---|---|---|---|
| count | 23090.000000 | 23090.000000 | 2.309000e+04 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 |
| mean | 3.532395 | 2.957687 | 2.337699e+09 | 0.544651 | 6239.185881 | 31248.316544 | 78148.127934 | 2.182763 | 664.433911 | 30.279385 |
| std | 1.628313 | 1.354260 | 3.819456e+09 | 0.498013 | 3574.207795 | 25789.096724 | 64514.324265 | 1.471115 | 309.893562 | 13.687618 |
| min | 0.000000 | 0.000000 | -9.984000e+09 | 0.000000 | 3.000000 | 1.000000 | 1.000000 | 1.000000 | 19.000000 | 2.000000 |
| 25% | 2.000000 | 2.000000 | 7.050000e+01 | 0.000000 | 3184.000000 | 5498.000000 | 13714.250000 | 1.000000 | 403.000000 | 18.000000 |
| 50% | 3.000000 | 4.000000 | 1.966500e+09 | 1.000000 | 6194.000000 | 51386.000000 | 128407.500000 | 1.000000 | 627.000000 | 29.000000 |
| 75% | 5.000000 | 4.000000 | 4.963000e+09 | 1.000000 | 9299.500000 | 56713.750000 | 141840.750000 | 3.000000 | 1004.000000 | 45.000000 |
| max | 6.000000 | 4.000000 | 9.999000e+09 | 1.000000 | 12434.000000 | 61584.000000 | 153996.000000 | 5.000000 | 1073.000000 | 48.000000 |
df_espanol.describe()
| DiasEnvio(Real) | DiasEnvio(Programado) | BeneficioPorPedido | RiesgoEntregaTardia | IDCliente | IDPedido | IDArticuloPedido | CantidadArticulosPedido | IDProducto | CategoriaProducto | |
|---|---|---|---|---|---|---|---|---|---|---|
| count | 23090.000000 | 23090.000000 | 2.309000e+04 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 | 23090.000000 |
| mean | 3.532395 | 2.957687 | 2.337699e+09 | 0.544651 | 6239.185881 | 31248.316544 | 78148.127934 | 2.182763 | 664.433911 | 30.279385 |
| std | 1.628313 | 1.354260 | 3.819456e+09 | 0.498013 | 3574.207795 | 25789.096724 | 64514.324265 | 1.471115 | 309.893562 | 13.687618 |
| min | 0.000000 | 0.000000 | -9.984000e+09 | 0.000000 | 3.000000 | 1.000000 | 1.000000 | 1.000000 | 19.000000 | 2.000000 |
| 25% | 2.000000 | 2.000000 | 7.050000e+01 | 0.000000 | 3184.000000 | 5498.000000 | 13714.250000 | 1.000000 | 403.000000 | 18.000000 |
| 50% | 3.000000 | 4.000000 | 1.966500e+09 | 1.000000 | 6194.000000 | 51386.000000 | 128407.500000 | 1.000000 | 627.000000 | 29.000000 |
| 75% | 5.000000 | 4.000000 | 4.963000e+09 | 1.000000 | 9299.500000 | 56713.750000 | 141840.750000 | 3.000000 | 1004.000000 | 45.000000 |
| max | 6.000000 | 4.000000 | 9.999000e+09 | 1.000000 | 12434.000000 | 61584.000000 | 153996.000000 | 5.000000 | 1073.000000 | 48.000000 |
# Para cada COLUMNA NUMERICA DE INTERES calcular la mediana, MEDIA Y DESVIACION ESTANDAR
# EJEMPLO PARA Benefit per order Y PRECIO DE PRODUCTO
# el precio del producto tiene valores vacios...ademas hay que convertirlo porque esta en formato Object..a numerico para hacer calculos
import re
import pandas as pd
def clean_price(price_str):
if pd.isna(price_str):
return None
# Convertir a string si no lo es
price_str = str(price_str)
# Eliminar espacios en blanco y caracteres no numéricos excepto punto y coma
cleaned = re.sub(r'[^\d.,]', '', price_str)
# Reemplazar coma por punto si hay más de un punto (asumiendo que la coma es el separador decimal)
if cleaned.count('.') > 1 and ',' in cleaned:
cleaned = cleaned.replace(',', '.')
# Si hay más de un punto, asumimos que todos menos el último son separadores de miles
parts = cleaned.split('.')
if len(parts) > 2:
integer_part = ''.join(parts[:-1])
decimal_part = parts[-1]
cleaned = f"{integer_part}.{decimal_part}"
try:
return float(cleaned)
except ValueError:
print(f"No se pudo convertir: {price_str}")
return None
# Aplicar la función a la columna 'Product Price' y mostrar los resultados
df_espanol['Clean Price'] = df['PrecioProducto'].apply(clean_price)
# Mostrar filas donde la limpieza falló
failed_conversions = df[df['PrecioProducto'].isna()]
print("Filas donde la conversión falló:")
print(failed_conversions[['PrecioProducto', 'Clean Price']])
# Calcular la mediana de los precios limpios
median_prices = df.groupby('Categoria')['Clean Price'].median()
print("\nMediana de precios de productos segun categoria:")
print(median_prices)
# Calcular la media de los precios limpios
media_prices = df.groupby('Categoria')['Clean Price'].mean()
print("\nMedia de precios de productos segun categoria:")
print(media_prices)
# Calcular la desviacion estandar de los precios limpios
std_prices = df.groupby('Categoria')['Clean Price'].std()
print("\nDesviacion estandar de productos segun categoria:")
print(std_prices)
# Mostrar estadísticas de la columna de precios limpios
print("\nEstadísticas de la columna de precio de productos:")
print(df['Clean Price'].describe())
Filas donde la conversión falló: Empty DataFrame Columns: [PrecioProducto, Clean Price] Index: [] Mediana de precios de productos segun categoria: Categoria Accessories 2498999.977 As Seen on TV! 9998999.786 Baseball & Softball 3499000.168 Boxing & MMA 8998999.786 Camping & Hiking 299980.011 Cardio Equipment 9998999.786 Cleats 5999000.168 Electronics 3198999.977 Fishing 399980.011 Fitness Accessories 3499000.168 Girls' Apparel 70.000 Golf Apparel 1998999.977 Golf Bags & Carts 1699900.055 Golf Balls 1798999.977 Golf Gloves 3999000.168 Golf Shoes 80.000 Hockey 22.000 Hunting & Shooting 2998999.977 Indoor/Outdoor Games 4997999.954 Kids' Golf Clubs 1999900.055 Lacrosse 2498999.977 Men's Footwear 1299900.055 Men's Golf Clubs 1324900.055 Shop By Sport 3999000.168 Soccer 7998999.786 Strength Training 189.000 Tennis & Racquet 4499000.168 Trade-In 1598999.977 Water Sports 1999900.055 Women's Apparel 50.000 Women's Golf Clubs 7998999.786 Name: Clean Price, dtype: float64 Media de precios de productos segun categoria: Categoria Accessories 2.499000e+06 As Seen on TV! 9.999000e+06 Baseball & Softball 4.362567e+06 Boxing & MMA 7.405708e+06 Camping & Hiking 2.999800e+05 Cardio Equipment 9.753777e+06 Cleats 5.999000e+06 Electronics 3.986990e+06 Fishing 3.999800e+05 Fitness Accessories 3.499000e+06 Girls' Apparel 1.312678e+06 Golf Apparel 1.721369e+06 Golf Bags & Carts 1.699900e+06 Golf Balls 1.774500e+06 Golf Gloves 5.901723e+06 Golf Shoes 8.122826e+01 Hockey 2.342308e+01 Hunting & Shooting 2.346087e+06 Indoor/Outdoor Games 4.998000e+06 Kids' Golf Clubs 5.153402e+06 Lacrosse 4.604263e+06 Men's Footwear 1.299900e+06 Men's Golf Clubs 2.857235e+06 Shop By Sport 3.879653e+06 Soccer 5.839288e+06 Strength Training 1.890000e+02 Tennis & Racquet 4.499000e+06 Trade-In 1.899081e+06 Water Sports 1.999900e+06 Women's Apparel 5.000000e+01 Women's Golf Clubs 6.459881e+06 Name: Clean Price, dtype: float64 Desviacion estandar de productos segun categoria: Categoria Accessories 0.000000e+00 As Seen on TV! 0.000000e+00 Baseball & Softball 1.615250e+06 Boxing & MMA 1.902672e+06 Camping & Hiking 0.000000e+00 Cardio Equipment 1.547033e+06 Cleats 0.000000e+00 Electronics 9.034617e+05 Fishing 0.000000e+00 Fitness Accessories 0.000000e+00 Girls' Apparel 1.885016e+06 Golf Apparel 3.644281e+05 Golf Bags & Carts 0.000000e+00 Golf Balls 2.190655e+05 Golf Gloves 3.338846e+06 Golf Shoes 1.795299e+01 Hockey 1.507722e+00 Hunting & Shooting 1.038113e+06 Indoor/Outdoor Games 0.000000e+00 Kids' Golf Clubs 4.335915e+06 Lacrosse 3.400022e+06 Men's Footwear 0.000000e+00 Men's Golf Clubs 3.413800e+06 Shop By Sport 6.421471e+05 Soccer 3.213214e+06 Strength Training 0.000000e+00 Tennis & Racquet 0.000000e+00 Trade-In 3.393157e+05 Water Sports 0.000000e+00 Women's Apparel 0.000000e+00 Women's Golf Clubs 3.646446e+06 Name: Clean Price, dtype: float64 Estadísticas de la columna de precio de productos: count 2.309000e+04 mean 3.035057e+06 std 2.934299e+06 min 2.200000e+01 25% 3.999800e+05 50% 1.999900e+06 75% 4.998000e+06 max 9.999000e+06 Name: Clean Price, dtype: float64
import re
import pandas as pd
def clean_Beneficio_por_pedido(benPP_str):
if pd.isna(benPP_str):
return None
# Convertir a string si no lo es
benPP_str = str(benPP_str)
# Eliminar espacios en blanco y caracteres no numéricos excepto punto y coma
cleaned = re.sub(r'[^\d.,]', '', benPP_str)
# Reemplazar coma por punto si hay más de un punto (asumiendo que la coma es el separador decimal)
if cleaned.count('.') > 1 and ',' in cleaned:
cleaned = cleaned.replace(',', '.')
# Si hay más de un punto, asumimos que todos menos el último son separadores de miles
parts = cleaned.split('.')
if len(parts) > 2:
integer_part = ''.join(parts[:-1])
decimal_part = parts[-1]
cleaned = f"{integer_part}.{decimal_part}"
try:
return float(cleaned)
except ValueError:
print(f"No se pudo convertir: {benPP_str}")
return None
# Aplicar la función a la columna 'Benefit per order' y mostrar los resultados
df['clean_Beneficio_por_pedido'] = df['BeneficioPorPedido'].apply(clean_Beneficio_por_pedido)
# Mostrar filas donde la limpieza falló
failed_conversions = df[df['clean_Beneficio_por_pedido'].isna()]
print("Filas donde la conversión falló:")
print(failed_conversions[['BeneficioPorPedido', 'clean_Beneficio_por_pedido']])
# Calcular la mediana de los precios limpios
median_prices = df.groupby('IDPedido')['clean_Beneficio_por_pedido'].median()
print("\nMediana de precios por producto:")
print(median_prices)
# Mostrar estadísticas de la columna de precios limpios
print("\nEstadísticas de la columna Beneficio por Pedido:")
print(df['clean_Beneficio_por_pedido'].describe())
Filas donde la conversión falló:
Empty DataFrame
Columns: [BeneficioPorPedido, clean_Beneficio_por_pedido]
Index: []
Mediana de precios por producto:
IDPedido
1 8.879000e+09
7 4.580000e+09
8 1.499750e+09
9 1.980000e+09
10 1.564000e+09
...
61580 1.161900e+09
61581 5.390000e+09
61582 1.050000e+09
61583 2.910000e+09
61584 2.291000e+09
Name: clean_Beneficio_por_pedido, Length: 7687, dtype: float64
Estadísticas de la columna Beneficio por Pedido:
count 2.309000e+04
mean 3.543691e+09
std 2.737705e+09
min 0.000000e+00
25% 1.329900e+09
50% 2.886000e+09
75% 5.481000e+09
max 9.999000e+09
Name: clean_Beneficio_por_pedido, dtype: float64
#histogramas, boxplots
# dias de entrega real
conteo_productos = df_espanol['DiasEnvio(Real)'].value_counts()
# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_productos.plot(kind='bar')
plt.xlabel('dias')
plt.ylabel('Frecuencia')
plt.title('dias de entrega')
plt.xticks(rotation=60) # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
dias_entrega_real=df_espanol.groupby(['DiasEnvio(Real)'])['IDPedido'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='DiasEnvio(Real)', y='Numero de Pedidos' , color='DiasEnvio(Real)',
)
fig.show()
#dias de entrega programado
conteo_productos = df_espanol['DiasEnvio(Programado)'].value_counts()
# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_productos.plot(kind='bar')
plt.xlabel('dias')
plt.ylabel('Frecuencia')
plt.title('dias de entrega')
plt.xticks(rotation=60) # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
dias_entrega_real=df_espanol.groupby(['DiasEnvio(Programado)'])['IDPedido'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='DiasEnvio(Programado)', y='Numero de Pedidos' , color='DiasEnvio(Programado)'
)
fig.show()
#FRECUENCIA DE PRODUCTOS
#Contamos y graficamos la frecuencia de los PRODUCTOS (muestra cuántas veces aparece cada PRODUCTO en los datos):
# Contar la frecuencia de cada producto
conteo_productos = df_espanol['NombreProducto'].value_counts()
# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_productos.plot(kind='bar')
plt.xlabel('Producto')
plt.ylabel('Frecuencia')
plt.title('Frecuencia de producto')
plt.xticks(rotation=60) # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
dias_entrega_real=df_espanol.groupby(['NombreProducto'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='NombreProducto', y='Numero de Pedidos' , color='NombreProducto'
)
fig.show()
#FRECUENCIA DE PRODUCTOS
#Contamos y graficamos la frecuencia de los PRODUCTOS (muestra cuántas veces aparece cada PRODUCTO en los datos):
# Contar la frecuencia de cada producto
conteo_categorias = df_espanol['CategoriaProducto'].value_counts()
# Crear un gráfico de barras
plt.figure(figsize=(12, 6))
conteo_categorias.plot(kind='barh')
plt.xlabel('Categoria')
plt.ylabel('Frecuencia')
plt.title('Frecuencia de categoria')
plt.xticks(rotation=60) # Rotar etiquetas del eje x para mayor legibilidad
plt.show()
dias_entrega_real=df_espanol.groupby(['CategoriaProducto'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='CategoriaProducto', y='Numero de Pedidos' , color='CategoriaProducto'
)
fig.show()
dias_entrega_real=df_espanol.groupby(['Categoria'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='Categoria', y='Numero de Pedidos' , color='Categoria'
)
fig.show()
#Agrupamos por categoria y creamos un gráfico de barras que muestra el recuento de productos para cada categoria.
df_espanol.groupby('Categoria').count()['NombreProducto'].plot(kind='bar')
<Axes: xlabel='Categoria'>
dias_entrega_real=df_espanol.groupby(['Categoria'])['IDProducto'].count().reset_index(name='Numero de Pedidos').sort_values(by= 'Numero de Pedidos', ascending= False)
fig=px.bar(dias_entrega_real, x='Categoria', y='Numero de Pedidos' , color='Categoria'
)
fig.show()
#Ahora buscamos el categoria con mayor :
df_espanol.groupby('Categoria').count()['Ventas'].plot(kind='barh')
<Axes: ylabel='Categoria'>
# Aplicar la función a la columna 'Benefit per order' y mostrar los resultados
df_espanol['Ventas'] = df_espanol['Ventas'].apply(clean_Beneficio_por_pedido)
#df_espanol = df_espanol.drop([']Ventas'], axis=1)
df_espanol['Ventas1'] = df_espanol['Ventas']/100000
dias_entrega_real=df_espanol.groupby(['Categoria'])['Ventas1'].sum().reset_index(name='Total ventas').sort_values(by= 'Total ventas', ascending= False)
fig=px.bar(dias_entrega_real, x='Categoria', y='Total ventas' , color='Categoria'
)
fig.show()
df_espanol.info()
<class 'pandas.core.frame.DataFrame'> Index: 23090 entries, 84 to 179628 Data columns (total 32 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Pago 23090 non-null object 1 DiasEnvio(Real) 23090 non-null int64 2 DiasEnvio(Programado) 23090 non-null int64 3 BeneficioPorPedido 23090 non-null float64 4 EstadoEntrega 23090 non-null object 5 RiesgoEntregaTardia 23090 non-null int64 6 Categoria 23090 non-null object 7 PaisCliente 23090 non-null object 8 IDCliente 23090 non-null int64 9 SegmentoCliente 23090 non-null object 10 PaisPedido 23090 non-null object 11 FechaPedido 23090 non-null object 12 IDPedido 23090 non-null int64 13 IDArticuloPedido 23090 non-null int64 14 PrecioArticuloPedido 23090 non-null object 15 CantidadArticulosPedido 23090 non-null int64 16 Ventas 23090 non-null float64 17 TotalArticulosPedido 23090 non-null object 18 GananciaPorPedido 23090 non-null object 19 RegionPedido 23090 non-null object 20 DestinoPedido 23090 non-null object 21 EstadoPedido 23090 non-null object 22 IDProducto 23090 non-null int64 23 CategoriaProducto 23090 non-null int64 24 NombreProducto 23090 non-null object 25 PrecioProducto 23090 non-null object 26 FechaEnvio 23090 non-null object 27 ModoEnvio 23090 non-null object 28 Clean Price 23090 non-null float64 29 clean_Beneficio_por_pedido 23090 non-null float64 30 Customer_ID_STR 23090 non-null object 31 Ventas1 23090 non-null float64 dtypes: float64(5), int64(9), object(18) memory usage: 5.8+ MB
data_delivery_status_region=df_espanol.groupby(['EstadoPedido', 'PaisPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoPedido', y='Number of Orders' , color='PaisPedido',
)
fig.show()
estado de las ordenes segun region - discriminado por estado de las ordenes
data_delivery_status_region=df_espanol.groupby(['EstadoPedido', 'RegionPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoPedido', y='Number of Orders' , color='RegionPedido',
)
fig.show()
data_delivery_status_region=df_espanol.groupby(['EstadoPedido', 'PaisCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoPedido', y='Number of Orders' , color='PaisCliente',
)
fig.show()
ESTO NO VA, PORQUE SE SACO LA CIUDAD............estado de las ordenes segun el codigo de estado
data_delivery_status_region=df_espanol.groupby(['EstadoEntrega', 'PaisPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoEntrega', y='Number of Orders' , color='PaisPedido',
)
fig.show()
data_delivery_status_region=df_espanol.groupby(['EstadoEntrega', 'RegionPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoEntrega', y='Number of Orders' , color='RegionPedido',
)
fig.show()
son iguales porque hay solo un pais por region
data_delivery_status_region=df_espanol.groupby(['EstadoEntrega', 'PaisCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_delivery_status_region, x='EstadoEntrega', y='Number of Orders' , color='PaisCliente',
)
fig.show()
solo para argentina*
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
df_argentina = df_espanol[df_espanol['PaisPedido'] == 'Argentina']
# Ahora realizamos el agrupamiento solo con los datos de Argentina
data_delivery_status_argentina = df_argentina.groupby('EstadoEntrega')['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by='Number of Orders', ascending=False)
# Creamos el gráfico de barras
fig = px.bar(data_delivery_status_argentina,
x='EstadoEntrega',
y='Number of Orders',
title='Delivery Status for Orders in Argentina')
# Mostramos el gráfico
fig.show()
#solo para cordoba
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
df_argentina = df_espanol[df_espanol['PaisCliente'] == 'Puerto Rico']
# Ahora realizamos el agrupamiento solo con los datos de Argentina
data_delivery_status_argentina = df_argentina.groupby('EstadoEntrega')['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by='Number of Orders', ascending=False)
# Creamos el gráfico de barras
fig = px.bar(data_delivery_status_argentina,
x='EstadoEntrega',
y='Number of Orders',
title='Estado de los pedidos que iran a Puerto Rico')
# Mostramos el gráfico
fig.show()
df_espanol['Customer_ID_STR']=df_espanol['IDCliente'].astype(str)
data_customers=df_espanol.groupby(['Customer_ID_STR'])['IDCliente'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_customers.head(20),x='Number of Orders', y='Customer_ID_STR' , color='Number of Orders' )
fig.show()
20 principales clientes segun la cantidad de pedidos de argentina
#solo para cordoba
# Primero, filtramos el DataFrame para incluir solo los datos de Argentina
df_argentina = df_espanol[df_espanol['PaisPedido'] == 'Argentina']
data_customers=df_argentina.groupby(['Customer_ID_STR'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.bar(data_customers.head(20),x='Number of Orders', y='Customer_ID_STR' , color='Number of Orders' )
fig.show()
----RECORDAR CAMBIAR "'CUSOTMER_ID_STR' EN TODOS ESTOS GRAFICOS, PONER UN NOMBRE APROPIADO"
#df_espanol.info()
df_espanol['Customer_ID_STR']=df_espanol['IDCliente'].astype(str)
data_customers_profit=df_espanol.groupby(['Customer_ID_STR'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(data_customers_profit.head(20),x='Ventas1', y='Customer_ID_STR' , color='Ventas1' )
fig.show()
#ACLARAR QUE LOS VALORES ESTAN DIVIDIDOS POR MILLONES
#Customer Segments
data_Customer_Segment=df_espanol.groupby(['SegmentoCliente'])['IDCliente'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
fig=px.pie(data_Customer_Segment, values='Number of Orders', names= 'SegmentoCliente' , title= 'Number of Orders of different Customer Segments',
width=600 , height=600 , color_discrete_sequence = px.colors.qualitative.D3)
fig.show()
#Customer Segments de cordoba
df_argentina = df_espanol[df_espanol['RegionPedido'] == 'South America']
data_Customer_Segment=df_argentina.groupby(['SegmentoCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
px.pie(data_Customer_Segment, values='Number of Orders', names= 'SegmentoCliente' , title= 'Number of Orders of different Customer Segments',
width=600 , height=600 , color_discrete_sequence = ["red", "green", "blue", "goldenrod", "magenta"])
#Customer Segments de cordoba
df_argentina = df_espanol[df_espanol['RegionPedido'] == 'Central America']
data_Customer_Segment=df_argentina.groupby(['SegmentoCliente'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= False)
px.pie(data_Customer_Segment, values='Number of Orders', names= 'SegmentoCliente' , title= 'Number of Orders of different Customer Segments',
width=600 , height=600 , color_discrete_sequence = px.colors.qualitative.G10)
#BUSCAR LAS COMBINACIONES DE COLORES QUE QUEDEN PAREJAS...........NO MUY DISTINTAS
#Categorias
data_Category_Name=df_espanol.groupby(['Categoria'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_Category_Name, x='Number of Orders',y = 'Categoria',color ='Number of Orders')
nombres de categorias para argentina
df_argentina = df_espanol[df_espanol['PaisPedido'] == 'Argentina']
data_Category_Name=df_argentina.groupby(['Categoria'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_Category_Name, x='Number of Orders',y = 'Categoria',color ='Number of Orders')
data_Region=df_espanol.groupby(['RegionPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_Region, x='Number of Orders',y = 'RegionPedido',color ='Number of Orders')
data_countries=df_espanol.groupby(['PaisPedido'])['IDPedido'].count().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_countries.head(20), x='Number of Orders',y = 'PaisPedido',color ='Number of Orders')
#FALTA SUMAR LAS VENTAS POR PAIS
#-----notar la escala es distinta, ver como se interpreta
data_countries=df_espanol.groupby(['PaisPedido'])['Ventas1'].sum().reset_index(name='Number of Orders').sort_values(by= 'Number of Orders', ascending= True)
px.bar(data_countries.head(20), x='Number of Orders',y = 'PaisPedido',color ='Number of Orders')
df_geo=df_espanol.groupby([ 'RegionPedido', 'PaisPedido'])['Ventas1'].sum().reset_index(name='Ventas').sort_values(by= 'Ventas', ascending= False)
df_geo
| RegionPedido | PaisPedido | Ventas | |
|---|---|---|---|
| 0 | Central America | Mexico | 282077.461240 |
| 2 | South America | Brasil | 170193.677838 |
| 1 | South America | Argentina | 41405.607661 |
import pandas as pd
import plotly.express as px
# Asumiendo que ya tienes tu DataFrame 'df_geo'
# Crear el gráfico de coropletas
fig = px.choropleth(df_geo,
locationmode='country names',
locations='PaisPedido',
color='Ventas',
hover_name='PaisPedido',
color_continuous_scale=px.colors.sequential.Plasma)
# Ajustar el diseño para una mejor visualización
fig.update_layout(
title_text='Mapa de Ganancias por País',
geo=dict(
showframe=False,
showcoastlines=True,
projection_type='equirectangular'
)
)
# Mostrar el gráfico
fig.show()
df_espanol.PaisPedido.unique()
array(['Brasil', 'Mexico', 'Argentina'], dtype=object)
# Ver si incluir si...el mapa no carga brasil
df_geo=df_espanol.groupby([ 'RegionPedido', 'PaisPedido'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
px.pie(df_geo, values='Ventas1', names= 'PaisPedido' , title= 'Number of Orders of different Customer Segments',
width=600 , height=600 , color_discrete_sequence = px.colors.qualitative.G10)
#HASTA ACA BIEN, SOLO HAY QUE VER QUE GRAFICOS QUEDAN Y CAMBIAR VARIABLES Y TITULOS DESCRIPTIVOS
# Asumiendo que tu DataFrame se llama 'df'
# 1. Verificar el tipo de datos actual y mostrar algunos ejemplos
print("Tipo de datos original de 'Ventas':", df_espanol['Ventas'].dtype)
print("\nEjemplos de valores en 'Ventas':")
print(df_espanol['Ventas'].head())
# 2. Función para convertir strings con formato europeo a float
def euro_to_float(value):
# Reemplazar el punto por nada (eliminar separador de miles)
# y la coma por punto (para decimales si los hubiera)
return float(value.replace('.', '').replace(',', '.'))
# 3. Aplicar la conversión a la columna 'Sales'
df_espanol['Ventas1'] = df_espanol['Ventas'].apply(euro_to_float)
# 4. Crear la nueva columna 'Sales_Reduced'
df_espanol['Sales_Reduced'] = df_espanol['Ventas'] / 10000
#Order Country
#df['Sales_Reduced'] = df['Sales'] / 10000
Tipo de datos original de 'Ventas': float64 Ejemplos de valores en 'Ventas': 84 150.0 86 150.0 87 150.0 88 150.0 89 150.0 Name: Ventas, dtype: float64
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Cell In[119], line 15 12 return float(value.replace('.', '').replace(',', '.')) 14 # 3. Aplicar la conversión a la columna 'Sales' ---> 15 df_espanol['Ventas1'] = df_espanol['Ventas'].apply(euro_to_float) 17 # 4. Crear la nueva columna 'Sales_Reduced' 18 df_espanol['Sales_Reduced'] = df_espanol['Ventas'] / 10000 File ~\anaconda3\lib\site-packages\pandas\core\series.py:4924, in Series.apply(self, func, convert_dtype, args, by_row, **kwargs) 4789 def apply( 4790 self, 4791 func: AggFuncType, (...) 4796 **kwargs, 4797 ) -> DataFrame | Series: 4798 """ 4799 Invoke function on values of Series. 4800 (...) 4915 dtype: float64 4916 """ 4917 return SeriesApply( 4918 self, 4919 func, 4920 convert_dtype=convert_dtype, 4921 by_row=by_row, 4922 args=args, 4923 kwargs=kwargs, -> 4924 ).apply() File ~\anaconda3\lib\site-packages\pandas\core\apply.py:1427, in SeriesApply.apply(self) 1424 return self.apply_compat() 1426 # self.func is Callable -> 1427 return self.apply_standard() File ~\anaconda3\lib\site-packages\pandas\core\apply.py:1507, in SeriesApply.apply_standard(self) 1501 # row-wise access 1502 # apply doesn't have a `na_action` keyword and for backward compat reasons 1503 # we need to give `na_action="ignore"` for categorical data. 1504 # TODO: remove the `na_action="ignore"` when that default has been changed in 1505 # Categorical (GH51645). 1506 action = "ignore" if isinstance(obj.dtype, CategoricalDtype) else None -> 1507 mapped = obj._map_values( 1508 mapper=curried, na_action=action, convert=self.convert_dtype 1509 ) 1511 if len(mapped) and isinstance(mapped[0], ABCSeries): 1512 # GH#43986 Need to do list(mapped) in order to get treated as nested 1513 # See also GH#25959 regarding EA support 1514 return obj._constructor_expanddim(list(mapped), index=obj.index) File ~\anaconda3\lib\site-packages\pandas\core\base.py:921, in IndexOpsMixin._map_values(self, mapper, na_action, convert) 918 if isinstance(arr, ExtensionArray): 919 return arr.map(mapper, na_action=na_action) --> 921 return algorithms.map_array(arr, mapper, na_action=na_action, convert=convert) File ~\anaconda3\lib\site-packages\pandas\core\algorithms.py:1743, in map_array(arr, mapper, na_action, convert) 1741 values = arr.astype(object, copy=False) 1742 if na_action is None: -> 1743 return lib.map_infer(values, mapper, convert=convert) 1744 else: 1745 return lib.map_infer_mask( 1746 values, mapper, mask=isna(values).view(np.uint8), convert=convert 1747 ) File lib.pyx:2972, in pandas._libs.lib.map_infer() Cell In[119], line 12, in euro_to_float(value) 9 def euro_to_float(value): 10 # Reemplazar el punto por nada (eliminar separador de miles) 11 # y la coma por punto (para decimales si los hubiera) ---> 12 return float(value.replace('.', '').replace(',', '.')) AttributeError: 'float' object has no attribute 'replace'
df_sales_country=df_espanol.groupby([ 'RegionPedido'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
px.bar(df_sales_country.head(10), x='Sales of Orders',y = 'RegionPedido',color ='Sales of Orders')
#Order Country
df_sales_country=df_espanol.groupby([ 'PaisPedido'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_country.head(10), x='Sales of Orders',y = 'PaisPedido',color ='Sales of Orders')
fig.show()
#Product
df_sales_country=df_espanol.groupby([ 'NombreProducto'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_country.head(10), x='Sales of Orders',y = 'NombreProducto',color ='Sales of Orders')
fig.show()
#Product and deliveray status
df_sales_pd=df_espanol.groupby([ 'NombreProducto', 'EstadoEntrega'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
px.bar(df_sales_pd.head(10), x='Sales of Orders',y = 'NombreProducto',color ='EstadoEntrega')
#Product and order region
df_sales_pr=df_espanol.groupby([ 'NombreProducto', 'RegionPedido'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_pr.head(10), x='Sales of Orders',y = 'NombreProducto',color ='RegionPedido')
fig.show()
#'Category Name'
df_sales_pr=df_espanol.groupby([ 'Categoria'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
px.bar(df_sales_pr.head(10), x='Ventas1',y = 'Categoria',color ='Categoria')
#'Type of payment
df_sales_pr=df_espanol.groupby([ 'Pago'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
px.bar(df_sales_pr.head(10), x='Ventas1',y = 'Pago',color ='Ventas1')
df_sales_tp=df_espanol.groupby([ 'NombreProducto','Pago'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_tp.head(100), x='Ventas1',y = 'Pago',color ='NombreProducto')
fig.show()
import datetime as dt
data_orderdate=df_espanol[['FechaEnvio', 'Ventas1']]
data_orderdate['order_date'] = pd.to_datetime(data_orderdate['FechaEnvio'])
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\1666086263.py:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate["Quarter"] = data_orderdate['order_date'].dt.quarter
data_orderdate["Month"] = data_orderdate['order_date'].dt.month
data_orderdate["year"] = data_orderdate['order_date'].dt.year
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate["Quarter"] = data_orderdate['order_date'].dt.quarter
data_orderdate["Month"] = data_orderdate['order_date'].dt.month
data_orderdate["year"] = data_orderdate['order_date'].dt.year
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:2: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\3482627655.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate['YearStr']=data_orderdate['year'].astype(str)
df_sales_year=data_orderdate.groupby([ 'YearStr'])['Ventas1'].sum().reset_index(name='Sales of Orders').sort_values(by= 'Sales of Orders', ascending= False)
fig=px.bar(df_sales_year, x='Sales of Orders',y = 'YearStr',color ='Sales of Orders')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\736912763.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate['QuarterStr']=data_orderdate['Quarter'].astype(str)
df_sales_quarter=data_orderdate.groupby([ 'YearStr','QuarterStr'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_quarter, x='Ventas1',y = 'QuarterStr',color ='YearStr')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\2549423506.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate['MonthStr']=data_orderdate['Month'].astype(str)
df_sales_m=data_orderdate.groupby([ 'QuarterStr', 'MonthStr'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_m, x='Ventas1',y = 'QuarterStr',color ='MonthStr')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\1003044912.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate['YearStr']=data_orderdate['Month'].astype(str)
df_sales_quarter=data_orderdate.groupby([ 'YearStr','Month'])['Ventas1'].sum().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_quarter, x='YearStr',y = 'Ventas1',color ='Month')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\2218752510.py:1: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
data_orderdate['YearStr'].unique()
array(['4', '3', '2', '1', '5', '6'], dtype=object)
# Primero, convertimos la columna a tipo datetime
df_espanol['FechaEnvio'] = pd.to_datetime(df_espanol['FechaEnvio'])
# Ahora creamos las nuevas columnas
df_espanol['dia'] = df_espanol['FechaEnvio'].dt.day
df_espanol['mes'] = df_espanol['FechaEnvio'].dt.month
df_espanol['anio'] = df_espanol['FechaEnvio'].dt.year
# Si quieres que el formato sea exactamente como 1-18-2018, puedes hacer:
df_espanol['fecha_formateada'] = df_espanol['FechaEnvio'].dt.strftime('%d-%m-%Y')
data_orderdate['YearStr']=data_orderdate['Month'].astype(str)
df_sales_quarter=df_espanol.groupby([ 'anio','mes'])['Ventas1'].count().reset_index(name='Ventas1').sort_values(by= 'Ventas1', ascending= False)
fig=px.bar(df_sales_quarter, x='anio',y = 'Ventas1',color ='Ventas1')
fig.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\1173019489.py:14: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
df_espanol.info()
<class 'pandas.core.frame.DataFrame'> Index: 23090 entries, 84 to 179628 Data columns (total 32 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Pago 23090 non-null object 1 DiasEnvio(Real) 23090 non-null int64 2 DiasEnvio(Programado) 23090 non-null int64 3 BeneficioPorPedido 23090 non-null float64 4 EstadoEntrega 23090 non-null object 5 RiesgoEntregaTardia 23090 non-null int64 6 Categoria 23090 non-null object 7 PaisCliente 23090 non-null object 8 IDCliente 23090 non-null int64 9 SegmentoCliente 23090 non-null object 10 PaisPedido 23090 non-null object 11 FechaPedido 23090 non-null object 12 IDPedido 23090 non-null int64 13 IDArticuloPedido 23090 non-null int64 14 PrecioArticuloPedido 23090 non-null object 15 CantidadArticulosPedido 23090 non-null int64 16 Ventas 23090 non-null float64 17 TotalArticulosPedido 23090 non-null object 18 GananciaPorPedido 23090 non-null object 19 RegionPedido 23090 non-null object 20 DestinoPedido 23090 non-null object 21 EstadoPedido 23090 non-null object 22 IDProducto 23090 non-null int64 23 CategoriaProducto 23090 non-null int64 24 NombreProducto 23090 non-null object 25 PrecioProducto 23090 non-null object 26 FechaEnvio 23090 non-null object 27 ModoEnvio 23090 non-null object 28 Clean Price 23090 non-null float64 29 clean_Beneficio_por_pedido 23090 non-null float64 30 Customer_ID_STR 23090 non-null object 31 Ventas1 23090 non-null float64 dtypes: float64(5), int64(9), object(18) memory usage: 5.8+ MB
titulo de esto...........
#separar la fecha
# Primero, convertimos la columna a tipo datetime
df_espanol['FechaEnvio'] = pd.to_datetime(df_espanol['FechaEnvio'])
# Ahora creamos las nuevas columnas
df_espanol['dia'] = df_espanol['FechaEnvio'].dt.day
df_espanol['mes'] = df_espanol['FechaEnvio'].dt.month
df_espanol['anio'] = df_espanol['FechaEnvio'].dt.year
# Si quieres que el formato sea exactamente como 1-18-2018, puedes hacer:
df_espanol['fecha_formateada'] = df_espanol['FechaEnvio'].dt.strftime('%d-%m-%Y')
df_espanol.head()
| Pago | DiasEnvio(Real) | DiasEnvio(Programado) | BeneficioPorPedido | EstadoEntrega | RiesgoEntregaTardia | Categoria | PaisCliente | IDCliente | SegmentoCliente | PaisPedido | FechaPedido | IDPedido | IDArticuloPedido | PrecioArticuloPedido | CantidadArticulosPedido | Ventas | TotalArticulosPedido | GananciaPorPedido | RegionPedido | DestinoPedido | EstadoPedido | IDProducto | CategoriaProducto | NombreProducto | PrecioProducto | FechaEnvio | ModoEnvio | Clean Price | clean_Beneficio_por_pedido | Customer_ID_STR | Ventas1 | dia | mes | anio | fecha_formateada | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 84 | PAYMENT | 4 | 2 | 2.347000e+09 | Late delivery | 1 | Women's Apparel | Puerto Rico | 8541 | Home Office | Brasil | 4/11/2017 15:49 | 56973 | 142502 | 50 | 3 | 150.0 | 144 | 2.346.999.931 | South America | Bahía | PENDING_PAYMENT | 502 | 24 | Nike Men's Dri-FIT Victory Golf Polo | 50 | 2017-04-15 15:49:00 | Second Class | 50.0 | 2.347000e+09 | 8541 | 0.0015 | 15 | 4 | 2017 | 15-04-2017 |
| 86 | PAYMENT | 6 | 2 | 4.366000e+09 | Late delivery | 1 | Women's Apparel | Puerto Rico | 3752 | Home Office | Mexico | 3/16/2017 2:54 | 55155 | 137932 | 50 | 3 | 150.0 | 139.5 | 4.365.999.985 | Central America | Distrito Federal | PENDING_PAYMENT | 502 | 24 | Nike Men's Dri-FIT Victory Golf Polo | 50 | 2017-03-22 02:54:00 | Second Class | 50.0 | 4.366000e+09 | 3752 | 0.0015 | 22 | 3 | 2017 | 22-03-2017 |
| 87 | PAYMENT | 2 | 2 | 1.320000e+09 | Shipping on time | 0 | Women's Apparel | Puerto Rico | 4673 | Home Office | Mexico | 3/29/2015 10:33 | 5991 | 14921 | 50 | 3 | 150.0 | 132 | 1.319.999.981 | Central America | Jalisco | PENDING_PAYMENT | 502 | 24 | Nike Men's Dri-FIT Victory Golf Polo | 50 | 2015-03-31 10:33:00 | Second Class | 50.0 | 1.320000e+09 | 4673 | 0.0015 | 31 | 3 | 2015 | 31-03-2015 |
| 88 | PAYMENT | 4 | 2 | 4.620000e+09 | Late delivery | 1 | Women's Apparel | Puerto Rico | 5367 | Home Office | Mexico | 2/3/2015 00:28 | 2263 | 5671 | 50 | 3 | 150.0 | 132 | 4.620.000.076 | Central America | Puebla | PENDING_PAYMENT | 502 | 24 | Nike Men's Dri-FIT Victory Golf Polo | 50 | 2015-02-07 00:28:00 | Second Class | 50.0 | 4.620000e+09 | 5367 | 0.0015 | 7 | 2 | 2015 | 07-02-2015 |
| 89 | PAYMENT | 4 | 2 | 1.044000e+09 | Late delivery | 1 | Women's Apparel | Puerto Rico | 5367 | Home Office | Mexico | 2/3/2015 00:28 | 2263 | 5669 | 50 | 3 | 150.0 | 130.5 | 1.043.999.958 | Central America | Puebla | PENDING_PAYMENT | 502 | 24 | Nike Men's Dri-FIT Victory Golf Polo | 50 | 2015-02-07 00:28:00 | Second Class | 50.0 | 1.044000e+09 | 5367 | 0.0015 | 7 | 2 | 2015 | 07-02-2015 |
#df.rename(columns={'Order Country':'OrderCountry'},inplace=True)
data_orderdate['YearStr']=df_espanol['anio'].astype(str)
fecha=df_espanol['anio'].astype(str)
# Calcular la producción total por año y Provincia
tendencias = df_espanol.groupby(['PaisPedido','anio'])['IDPedido'].count().reset_index()
# Visualizar tendencias a lo largo de los años
plt.figure(figsize=(12, 6))
for OrderCountry in tendencias['PaisPedido'].unique():
data = tendencias[tendencias['PaisPedido'] == OrderCountry]
plt.plot(data['anio'], data['IDPedido'], label=OrderCountry)
plt.xlabel('Año')
plt.ylabel('cantidad de pedidos')
plt.title('Tendencias en en pedidos por Años')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True)
plt.show()
C:\Users\Usuario\AppData\Local\Temp\ipykernel_18968\2151799396.py:3: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
import pandas as pd
import plotly.graph_objects as go
# Asumiendo que tu DataFrame se llama 'tendencias'
# y tiene las columnas 'PaisPedido', 'anio', y 'IDPedido'
# Crear una figura
fig = go.Figure()
# Iterar a través de países únicos
for pais in tendencias['PaisPedido'].unique():
# Filtrar datos para el país actual
data_pais = tendencias[tendencias['PaisPedido'] == pais]
# Agregar una línea para cada país
fig.add_trace(go.Scatter(
x=data_pais['anio'],
y=data_pais['IDPedido'],
mode='lines',
name=pais
))
# Personalizar el diseño del gráfico
fig.update_layout(
title='Tendencias en pedidos por Años',
xaxis_title='Año',
yaxis_title='Cantidad de Pedidos',
legend_title_text='País',
legend=dict(
yanchor="top",
y=0.99,
xanchor="left",
x=0.01
)
)
# Agregar líneas de cuadrícula
fig.update_xaxes(showgrid=True)
fig.update_yaxes(showgrid=True)
# Mostrar el gráfico
fig.show()
#df_argentina.rename(columns={'Order Country':'OrderCountry'},inplace=True)
#df_argentina = df[df['OrderCountry'] == 'Argentina']
#df_argentina.rename(columns={'Order City':'OrderCity'},inplace=True)
#data_orderdate['YearStr']=df['anio'].astype(str)
#fecha=df_argentina['anio'].astype(str)
# Calcular la producción total por año y Provincia
tendencias = df_espanol.groupby(['RegionPedido','anio'])['IDPedido'].count().reset_index()
# Visualizar tendencias a lo largo de los años
plt.figure(figsize=(12, 6))
for OrderCity in tendencias['RegionPedido'].unique():
data = tendencias[tendencias['RegionPedido'] == OrderCity]
plt.plot(data['anio'], data['IDPedido'], label=OrderCity)
plt.xlabel('Año')
plt.ylabel('cantidad de pedidos')
plt.title('Tendencias en en pedidos por meses')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True)
plt.show()
import pandas as pd
import plotly.graph_objects as go
# Asumiendo que tu DataFrame se llama 'tendencias'
# y tiene las columnas 'PaisPedido', 'anio', y 'IDPedido'
# Crear una figura
fig = go.Figure()
# Iterar a través de países únicos
for pais in tendencias['RegionPedido'].unique():
# Filtrar datos para el país actual
data_pais = tendencias[tendencias['RegionPedido'] == pais]
# Agregar una línea para cada país
fig.add_trace(go.Scatter(
x=data_pais['anio'],
y=data_pais['IDPedido'],
mode='lines',
name=pais
))
# Personalizar el diseño del gráfico
fig.update_layout(
title='Tendencias en pedidos por Años',
xaxis_title='Año',
yaxis_title='Cantidad de Pedidos',
legend_title_text='País',
legend=dict(
yanchor="top",
y=0.99,
xanchor="left",
x=0.01
)
)
# Agregar líneas de cuadrícula
fig.update_xaxes(showgrid=True)
fig.update_yaxes(showgrid=True)
# Mostrar el gráfico
fig.show()
df_espanol['PrecioProducto'] = df_espanol['PrecioProducto'].apply(clean_Beneficio_por_pedido)
df_espanol['Precio2'] = df_espanol['PrecioProducto']/1000
# vamos a probar agregar una columna donde se divida el valor de la orden para ver si se puede dibujar
#df.rename(columns={'Order Country':'OrderCountry'},inplace=True)
#data_orderdate['YearStr']=df['anio'].astype(str)
#fecha=df['anio'].astype(str)
# Calcular la producción total por año y Provincia
tendencias = df_espanol.groupby(['NombreProducto','anio'])['PrecioProducto'].sum().reset_index()
# Visualizar tendencias a lo largo de los años
plt.figure(figsize=(12, 6))
for OrderCountry in tendencias['NombreProducto'].unique():
data = tendencias[tendencias['NombreProducto'] == OrderCountry]
plt.plot(data['anio'], data['PrecioProducto'], label=OrderCountry)
plt.xlabel('Año')
plt.ylabel('cantidad de pedidos')
plt.title('Tendencias en en pedidos por Años')
plt.legend(loc='upper left', bbox_to_anchor=(1, 1))
plt.grid(True)
plt.show()
#CANTIDAD DE PEDIDOS POR AÑO SEGUN EL PRODUCTO
import pandas as pd
import plotly.graph_objects as go
# Asumiendo que tu DataFrame se llama 'tendencias'
# y tiene las columnas 'PaisPedido', 'anio', y 'IDPedido'
# Crear una figura
fig = go.Figure()
# Iterar a través de países únicos
for pais in tendencias['NombreProducto'].unique():
# Filtrar datos para el país actual
data_pais = tendencias[tendencias['NombreProducto'] == pais]
# Agregar una línea para cada país
fig.add_trace(go.Scatter(
x=data_pais['anio'],
y=data_pais['IDPedido'],
mode='lines',
name=pais
))
# Personalizar el diseño del gráfico
fig.update_layout(
title='Tendencias en pedidos por Años',
xaxis_title='Año',
yaxis_title='Cantidad de Pedidos',
legend_title_text='País',
legend=dict(
yanchor="top",
y=0.99,
xanchor="left",
x=0.01
)
)
# Agregar líneas de cuadrícula
fig.update_xaxes(showgrid=True)
fig.update_yaxes(showgrid=True)
# Mostrar el gráfico
fig.show()
#Agregar los boxplots
#ejemplo de codigo
# REEMPLAZAR POR EL OTRO CODIGO
import plotly.express as px
df = px.data.tips()
fig = px.box(df, y="total_bill")
fig.show()
Distribución de Variables: Realizar un análisis de las variables individuales para entender su distribución. Utilizar histogramas, boxplots y estadísticas descriptivas (media, mediana, desviación estándar, etc.) para las variables numéricas. Para las variables categóricas, calcular frecuencias y proporciones. Identificación de Outliers: Detectar posibles outliers en las variables numéricas utilizando técnicas como el análisis de boxplots o el cálculo del z-score.
Relaciones entre Variables: Analizar la relación entre pares de variables para identificar patrones o correlaciones. Utilizar gráficos de dispersión (scatter plots) y mapas de calor de correlación (heatmaps) para evaluar la relación entre variables numéricas. Comparaciones Categóricas: Explorar cómo las variables categóricas afectan a las variables numéricas, utilizando gráficos de barras y boxplots.
Tratamiento de Valores Faltantes: Identificar valores faltantes en el conjunto de datos. Aplicar métodos adecuados para el tratamiento de estos valores, ya sea mediante imputación, eliminación de filas/columnas o sustitución con valores medianos/modales. Normalización y Transformación: Realizar transformaciones necesarias para preparar los datos para el análisis posterior. Esto puede incluir normalización y estandarización
# solo faltan algo de analisis bivariado y limpieza
# hay que definir bien las columnas que quedan si se van a utilizar luego para la 3 entrega
df_espanol['anio'].unique()
array([2017, 2015])
#FALTAN AÑOS,.............VER LA FUNCION QUE DIVIDE LA FECHA DE ENVIO